package QianFeng07.IODemo;

import java.io.*;
import java.util.Enumeration;
import java.util.Vector;

/**
 * 文件分割合并示例
 *
 * 合并使用上合并流
 * SequenceInputStream表示其他输入流的逻辑串联。
 **/
public class FileDivisionMergeDemo {
    public static void main(String[] args) {
        File file = new File("F:\\Test\\test.mp4");
        //文件分割
        //division(file,1024*1024*15);
        //文件合并
        try {
            InputStream inputStream1 = new FileInputStream(new File("F:\\Test\\1-temp-test.mp4"));
            InputStream inputStream2 = new FileInputStream(new File("F:\\Test\\2-temp-test.mp4"));
            InputStream inputStream3 = new FileInputStream(new File("F:\\Test\\3-temp-test.mp4"));
            InputStream inputStream4 = new FileInputStream(new File("F:\\Test\\4-temp-test.mp4"));

            //集合工具类，内部实现使用了数组
            Vector<InputStream> vector = new Vector<InputStream>();
            vector.add(inputStream1);
            vector.add(inputStream2);
            vector.add(inputStream3);
            vector.add(inputStream4);
            //Enumeration接口中定义了一些方法，通过这些方法可以枚举（一次获得一个）对象集合中的元素
            Enumeration<InputStream> enumeration = vector.elements();
            Merge(enumeration);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 文件分割
     * targetFile 要分割的目标文件
     * cutSize 每个文件的大小
    **/
    private static void division(File targetFile,long cutSize) {
        if (targetFile == null) return;
        //计算总分割的文件数   有余数就+1，没余数就整除
        int numFiles = targetFile.length() % cutSize == 0 ?
                (int) (targetFile.length() / cutSize) : (int) (targetFile.length() / cutSize + 1);
        //构造一个文件输入流
        try {
            BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(targetFile));
            BufferedOutputStream bufferedOutputStream = null;

            byte[] bytes = null;//每次要读取的字节数
            int len = -1;//表示每次实际读取长度
            int count = 0;//每一个文件要读取的次数
            //循环次数为生成文件的个数
            for (int i = 0; i < numFiles; i++) {
                bufferedOutputStream = new BufferedOutputStream(
                        new FileOutputStream(new File("F:\\Test\\" + (i + 1) + "-temp-" + targetFile.getName())));
                //文件小直接读取
                if (cutSize <= 1024) {
                    bytes = new byte[(int) cutSize];
                } else { //文件大则得到每个文件读取的次数
                    bytes = new byte[1024];
                    count = (int) cutSize / 1024;
                }
                //循环读取文件
                while (count > 0 && (len = bufferedInputStream.read(bytes)) != -1) {
                    bufferedOutputStream.write(bytes, 0, len);
                    bufferedOutputStream.flush();
                    count--;
                }
                //计算每个文件大小除以1024的余数，决定是否要在读取一次
                if (cutSize % 1024 != 0) {
                    bytes = new byte[(int) cutSize % 1024];
                    len = bufferedInputStream.read(bytes);
                    bufferedOutputStream.write(bytes, 0, len);
                    bufferedOutputStream.flush();
                    bufferedOutputStream.close();
                }
            }
            bufferedInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    /**
     * 文件合并
     * 合并流:
     * SequenceInputStream表示其他输入流的逻辑串联。它从输入流的有序集合开始，并从第一个输入流开始读取，
     * 直到到达文件末尾，接着从第二个输入流读取，依次类推，直到到达包含的最后一个输入流的文件末尾为止。
     **/
    private static void Merge(Enumeration<InputStream> enumeration) {
        //构造一个合并流
        SequenceInputStream sis = new SequenceInputStream(enumeration);
        try {
            BufferedOutputStream bos = new BufferedOutputStream(
                    new FileOutputStream("F:\\Test\\test1.mp4"));
            byte[] bytes = new byte[1024];
            int len = -1;
            while ((len = sis.read(bytes)) != -1) {
                bos.write(bytes, 0, len);
                bos.flush();
            }
            bos.close();
            sis.close();
            System.out.println("合并完成");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}
